package com.atguigu.product.service.imp;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.atguigu.order.Order;
import com.atguigu.product.Product;
import com.atguigu.product.feign.ProductFeignClient;
import com.atguigu.product.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Service

public class OrderServiceImpl implements OrderService {
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Autowired
    private ProductFeignClient productFeignClient;

    @Override
    @SentinelResource(value = "createOrder", fallback = "createOrderCallBack")
    public Order createOrder(Long userId, Long productId) {
//        Product productRemote = getProductRemote(productId);
//        Product productRemote = getProductRemoteWithLoadBlanceAnnotaion(productId);
        //远程调用
        Product productRemote = productFeignClient.getProductId(productId);
        Order order = new Order();
        order.setId(1);
        order.setName("苹果" + userId);
        order.setAddress("aaaaa");
        order.setPrice(productRemote.getPrice().multiply(new BigDecimal(productRemote.getUnm())));
        order.setProductId(1);
        order.setOrderList(Arrays.asList(productRemote));
        return order;

    }

    public Order createOrderCallBack(Long userId, Long productId, BlockException e) {
        Order order = new Order();
        order.setId(0);
        order.setPrice(new BigDecimal("0"));
        order.setUserId(Math.toIntExact(userId));
        order.setName("未知用户");
        order.setAddress("异常信息" + e.getClass());
        return order;

    }


    private Product getProductRemote(Long productId) {
        //拿到机器的ipservice-product
        List<ServiceInstance> product = discoveryClient.getInstances("service-product");
        ServiceInstance serviceInstance = product.get(0);
        //url
        String url = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/productId/" + productId;
        log.info("远程请求:{}", url);
        //远程调用
        Product product1 = restTemplate.getForObject(url, Product.class);
        return product1;
    }

    //    负载均衡发送请求 进阶2
    private Product getProductRemoteWithLoadBlance(Long productId) {
        ServiceInstance choose = loadBalancerClient.choose("service-product");
        //远程URL
        String url = "http://" + choose.getHost() + ":" + choose.getPort() + "/productId/" + productId;
        log.info("远程请求：{}", url);
        //2、给远程发送请求
        Product product1 = restTemplate.getForObject(url, Product.class);
        return product1;

    }

    //    进阶3 基于注解负载均衡发送请求
    private Product getProductRemoteWithLoadBlanceAnnotaion(Long productId) {
//    ServiceInstance choose = loadBalancerClient.choose("service-product");
//    //远程URL
//    String url = "http://" + choose.getHost() + ":" + choose.getPort() + "/productId/" + productId;
        String url = "http://service-product/productId/" + productId;
        //2、给远程发送请求
        Product product1 = restTemplate.getForObject(url, Product.class);
        return product1;

    }
}
